#include "wmi_connection.h"

using namespace std;
using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;

WMI_HResult* 
WMI_Connection::executeQuery(const wchar_t* wql_query)
{
	DOMConfigurator::configure("LogConfig.xml");
	HRESULT hres;
	LoggerPtr loggerWConn(Logger::getLogger("loggerWConn"));
	stringstream out;

	hres = _pSvc->ExecQuery(
		bstr_t(WQL.c_str()), 
        bstr_t(wql_query),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &_pEnumerator);
	
    if (FAILED(hres))
    {
        WMI_HResult* whres = new WMI_HResult(QUERY_FAILED, hres);
        LOG4CXX_ERROR(loggerWConn, whres->toString());
        close();        
		CoUninitialize();
        return whres;               // Program has failed.
    }

   // Step 8: -------------------------------------------------
   // Secure the enumerator proxy
   hres = CoSetProxyBlanket(       
       _pEnumerator,                 // the proxy to set
       RPC_C_AUTHN_WINNT,            // authentication service
       RPC_C_AUTHZ_NONE,             // authorization service
       NULL,                         // Server principal name
       RPC_C_AUTHN_LEVEL_CALL,       // authentication level
       RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
       NULL,                         // client identity 
       EOAC_NONE                     // proxy capabilities     
    );

    if (FAILED(hres))
    {
        WMI_HResult* whres = new WMI_HResult(PROXY_NOT_SET, hres);
		LOG4CXX_ERROR(loggerWConn, whres->toString());
		close();
        return whres;               // Program has failed.
    }

	return new WMI_HResult(W_OK, 0);
}

WMI_HResult* 
WMI_Connection::getClassObject(const wchar_t* className,IWbemClassObject** classObject)
{
	DOMConfigurator::configure("LogConfig.xml");
	HRESULT hres;	
	LoggerPtr loggerWConn(Logger::getLogger("loggerWConn"));
	stringstream out;

	BSTR Name =(BSTR) className;
	hres = _pSvc->GetObject(Name, 0, NULL, classObject, NULL);
	
    if (FAILED(hres))
    {
        WMI_HResult* whres = new WMI_HResult(QUERY_FAILED, hres);
        LOG4CXX_ERROR(loggerWConn, whres->toString());
        _pSvc->Release();
		CoUninitialize();
        return whres;               // Program has failed.
    }

	return new WMI_HResult(W_OK, 0);
}

void 
WMI_Connection::close()
{	
	if (_pEnumerator != NULL)
    {
		_pEnumerator->Release();
    }

	CoUninitialize();
}